﻿using System;
using System.Collections.Generic;
using System.Text;
using Vortex.Drawing;
using Vortex.SceneFramework.CSS;

namespace Vortex.SceneFramework {
	/// <summary>
	/// Contains methods for drawing style parts
	/// </summary>
	public static class StyleDrawer {

		/// <summary>
		/// Draws the background using style.
		/// </summary>
		/// <param name="canvas">The taret drawing canvas.</param>
		/// <param name="style">The element's style.</param>
		/// <param name="region">The background region.</param>
		public static void DrawBackground(Canvas2D canvas, NodeStyle style, Rect region) {
			Sprite background = style.Get<Sprite>(Styles.Background);
			if (null != background) {
				//do magic with colors
				ColorU backgroundColor = style.Get<ColorU>(Styles.BackgroundColor);
				float backgroundOpacity = style.Get<float>(Styles.BackgroundOpacity);
				if (backgroundOpacity < 1) {
					backgroundColor = backgroundColor.MultiplyAlpha(backgroundOpacity);
				}

				//apply blending as it should be
				using (canvas <= style.Get<Blending>(Styles.BackgroundBlending)) {
					//get frame size if possible
					Vector2 backgroundFrameSize = style.Get<Vector2>(Styles.BackgroundFrameSize);

					//try get/apply background padding
					Rect backgroundPadding = style.Get<Rect>(Styles.BackgroundPadding);
					region = region.Deflate(backgroundPadding) + style.Get<Vector2>(Styles.BackgroundOffset);

					//if background frame is empty then just stretch sprite to element bounds
					if (backgroundFrameSize.IsEmpty) {
						canvas.DrawSprite(region, background, backgroundColor);
					} else {
						if (backgroundFrameSize.X * 2 >= region.Width) backgroundFrameSize.X = region.Width * 0.5f;
						if (backgroundFrameSize.Y * 2 >= region.Height) backgroundFrameSize.Y = region.Height * 0.5f;
						canvas.DrawFrame(region, background, backgroundFrameSize, true, backgroundColor);
					}
				}
			}
		}

		/// <summary>
		/// Draws the foreground using style.
		/// </summary>
		/// <param name="canvas">The canvas.</param>
		/// <param name="style">The style.</param>
		/// <param name="region">The region.</param>
		public static void DrawForeground(Canvas2D canvas, NodeStyle style, Rect region) {
			Sprite foreground = style.Get<Sprite>(Styles.Foreground);
			if (null != foreground) {
				//do magic with colors
				ColorU foregroundColor = style.Get<ColorU>(Styles.ForegroundColor);
				float foregroundOpacity = style.Get<float>(Styles.ForegroundOpacity);
				if (foregroundOpacity < 1) {
					foregroundColor = foregroundColor.MultiplyAlpha(foregroundOpacity);
				}

				//apply blending as it should be
				using (canvas <= style.Get<Blending>(Styles.ForegroundBlending)) {
					//get frame size if possible
					Vector2 foregroundFrameSize = style.Get<Vector2>(Styles.ForegroundFrameSize);

					//try get/apply foreground padding
					Rect foregroundPadding = style.Get<Rect>(Styles.ForegroundPadding);
					region = region.Deflate(foregroundPadding) + style.Get<Vector2>(Styles.ForegroundOffset);

					//if foreground frame is empty then just stretch sprite to element bounds
					if (foregroundFrameSize.IsEmpty) {
						canvas.DrawSprite(region, foreground, foregroundColor);
					} else {
						if (foregroundFrameSize.X * 2 >= region.Width) foregroundFrameSize.X = region.Width * 0.5f;
						if (foregroundFrameSize.Y * 2 >= region.Height) foregroundFrameSize.Y = region.Height * 0.5f;
						canvas.DrawFrame(region, foreground, foregroundFrameSize, true, foregroundColor);
					}
				}
			}
		}

		/// <summary>
		/// Draws the text using style.
		/// </summary>
		/// <param name="canvas">The canvas.</param>
		/// <param name="style">The style.</param>
		/// <param name="region">The region.</param>
		/// <param name="text">The text.</param>
		public static void DrawText(Canvas2D canvas, NodeStyle style, Rect region, string text) {
			//text color is optional, default is blank
			ColorU textColor = style.Get<ColorU>(Styles.TextColor);

			//background opacity is optional, apply it only if specified
			float textOpacity = style.Get<float>(Styles.TextOpacity);
			if (textOpacity < 1) {
				textColor = textColor.MultiplyAlpha(textOpacity);
			}

			//try to get custom background blending
			using (canvas <= style.Get<Blending>(Styles.TextBlending)) {
				//draw text inside rect
				canvas.DrawTextLayout(
					style.Get<SpriteFont>(Styles.TextFont),
					region.Deflate(style.Get<Rect>(Styles.TextPadding)) + style.Get<Vector2>(Styles.TextOffset),
					text,
					style.Get<TextLayout>(Styles.TextLayout),
					textColor
				);
			}
		}
	}
}
